home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / r_things.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  21KB  |  1,009 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Refresh of things, i.e. objects represented by sprites.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: r_things.c,v 1.5 1997/02/03 16:47:56 b1 Exp $";
  27.  
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31.  
  32.  
  33. #include "doomdef.h"
  34. #include "m_swap.h"
  35.  
  36. #include "i_system.h"
  37. #include "z_zone.h"
  38. #include "w_wad.h"
  39.  
  40. #include "r_local.h"
  41.  
  42. #include "doomstat.h"
  43.  
  44.  
  45.  
  46. #define MINZ                (FRACUNIT*4)
  47. #define BASEYCENTER            100
  48.  
  49. //void R_DrawColumn (void);
  50. //void R_DrawFuzzColumn (void);
  51.  
  52.  
  53.  
  54. typedef struct
  55. {
  56.     int        x1;
  57.     int        x2;
  58.     
  59.     int        column;
  60.     int        topclip;
  61.     int        bottomclip;
  62.  
  63. } maskdraw_t;
  64.  
  65.  
  66.  
  67. //
  68. // Sprite rotation 0 is facing the viewer,
  69. //  rotation 1 is one angle turn CLOCKWISE around the axis.
  70. // This is not the same as the angle,
  71. //  which increases counter clockwise (protractor).
  72. // There was a lot of stuff grabbed wrong, so I changed it...
  73. //
  74. fixed_t        pspritescale;
  75. fixed_t        pspriteiscale;
  76.  
  77. lighttable_t**    spritelights;
  78.  
  79. // constant arrays
  80. //  used for psprite clipping and initializing clipping
  81. short        negonearray[SCREENWIDTH];
  82. short        screenheightarray[SCREENWIDTH];
  83.  
  84.  
  85. //
  86. // INITIALIZATION FUNCTIONS
  87. //
  88.  
  89. // variables used to look up
  90. //  and range check thing_t sprites patches
  91. spritedef_t*    sprites;
  92. int        numsprites;
  93.  
  94. FAR spriteframe_t    sprtemp[29];
  95. int        maxframe;
  96. char*        spritename;
  97.  
  98.  
  99.  
  100.  
  101. //
  102. // R_InstallSpriteLump
  103. // Local function for R_InitSprites.
  104. //
  105. void
  106. R_InstallSpriteLump
  107. ( int        lump,
  108.   unsigned    frame,
  109.   unsigned    rotation,
  110.   boolean    flipped )
  111. {
  112.     int        r;
  113.     
  114.     if (frame >= 29 || rotation > 8)
  115.     I_Error("R_InstallSpriteLump: "
  116.         "Bad frame characters in lump %i", lump);
  117.     
  118.     if ((int)frame > maxframe)
  119.     maxframe = frame;
  120.         
  121.     if (rotation == 0)
  122.     {
  123.     // the lump should be used for all rotations
  124.     if (sprtemp[frame].rotate == false)
  125.         I_Error ("R_InitSprites: Sprite %s frame %c has "
  126.              "multip rot=0 lump", spritename, 'A'+frame);
  127.  
  128.     if (sprtemp[frame].rotate == true)
  129.         I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  130.              "and a rot=0 lump", spritename, 'A'+frame);
  131.             
  132.     sprtemp[frame].rotate = false;
  133.     for (r=0 ; r<8 ; r++)
  134.     {
  135.         sprtemp[frame].lump[r] = lump - firstspritelump;
  136.         sprtemp[frame].flip[r] = (byte)flipped;
  137.     }
  138.     return;
  139.     }
  140.     
  141.     // the lump is only used for one rotation
  142.     if (sprtemp[frame].rotate == false)
  143.     I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  144.          "and a rot=0 lump", spritename, 'A'+frame);
  145.         
  146.     sprtemp[frame].rotate = true;
  147.  
  148.     // make 0 based
  149.     rotation--;        
  150.     if (sprtemp[frame].lump[rotation] != -1)
  151.     I_Error ("R_InitSprites: Sprite %s : %c : %c "
  152.          "has two lumps mapped to it",
  153.          spritename, 'A'+frame, '1'+rotation);
  154.         
  155.     sprtemp[frame].lump[rotation] = lump - firstspritelump;
  156.     sprtemp[frame].flip[rotation] = (byte)flipped;
  157. }
  158.  
  159.  
  160.  
  161.  
  162. //
  163. // R_InitSpriteDefs
  164. // Pass a null terminated list of sprite names
  165. //  (4 chars exactly) to be used.
  166. // Builds the sprite rotation matrixes to account
  167. //  for horizontally flipped sprites.
  168. // Will report an error if the lumps are inconsistant. 
  169. // Only called at startup.
  170. //
  171. // Sprite lump names are 4 characters for the actor,
  172. //  a letter for the frame, and a number for the rotation.
  173. // A sprite that is flippable will have an additional
  174. //  letter/number appended.
  175. // The rotation character can be 0 to signify no rotations.
  176. //
  177. void R_InitSpriteDefs (char** namelist) 
  178.     char**    check;
  179.     int        i;
  180.     int        l;
  181.     int        intname;
  182.     int        frame;
  183.     int        rotation;
  184.     int        start;
  185.     int        end;
  186.     int        patched;
  187.         
  188.     // count the number of sprite names
  189.     check = namelist;
  190.     while (*check != NULL)
  191.     check++;
  192.  
  193.     numsprites = check-namelist;
  194.     
  195.     if (!numsprites)
  196.     return;
  197.         
  198.     sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);
  199.     
  200.     start = firstspritelump-1;
  201.     end = lastspritelump+1;
  202.     
  203.     // scan all the lump names for each of the names,
  204.     //  noting the highest frame letter.
  205.     // Just compare 4 characters as ints
  206.     for (i=0 ; i<numsprites ; i++)
  207.     {
  208.     spritename = namelist[i];
  209.     memset (sprtemp,-1, sizeof(sprtemp));
  210.         
  211.     maxframe = -1;
  212.     intname = *(int *)namelist[i];
  213.     
  214.     // scan the lumps,
  215.     //  filling in the frames for whatever is found
  216.     for (l=start+1 ; l<end ; l++)
  217.     {
  218.         if (*(int *)lumpinfo[l].name == intname)
  219.         {
  220.         frame = lumpinfo[l].name[4] - 'A';
  221.         rotation = lumpinfo[l].name[5] - '0';
  222.  
  223.         if (modifiedgame)
  224.             patched = W_GetNumForName (lumpinfo[l].name);
  225.         else
  226.             patched = l;
  227.  
  228.         R_InstallSpriteLump (patched, frame, rotation, false);
  229.  
  230.         if (lumpinfo[l].name[6])
  231.         {
  232.             frame = lumpinfo[l].name[6] - 'A';
  233.             rotation = lumpinfo[l].name[7] - '0';
  234.             R_InstallSpriteLump (l, frame, rotation, true);
  235.         }
  236.         }
  237.     }
  238.     
  239.     // check the frames that were found for completeness
  240.     if (maxframe == -1)
  241.     {
  242.         sprites[i].numframes = 0;
  243.         continue;
  244.     }
  245.         
  246.     maxframe++;
  247.     
  248.     for (frame = 0 ; frame < maxframe ; frame++)
  249.     {
  250.         switch ((int)sprtemp[frame].rotate)
  251.         {
  252.           case -1:
  253.         // no rotations were found for that frame at all
  254.         I_Error ("R_InitSprites: No patches found "
  255.              "for %s frame %c", namelist[i], frame+'A');
  256.         break;
  257.         
  258.           case 0:
  259.         // only the first rotation is needed
  260.         break;
  261.             
  262.           case 1:
  263.         // must have all 8 frames
  264.         for (rotation=0 ; rotation<8 ; rotation++)
  265.             if (sprtemp[frame].lump[rotation] == -1)
  266.             I_Error ("R_InitSprites: Sprite %s frame %c "
  267.                  "is missing rotations",
  268.                  namelist[i], frame+'A');
  269.         break;
  270.         }
  271.     }
  272.     
  273.     // allocate space for the frames present and copy sprtemp to it
  274.     sprites[i].numframes = maxframe;
  275.     sprites[i].spriteframes = 
  276.         Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
  277.     memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
  278.     }
  279.  
  280. }
  281.  
  282.  
  283.  
  284.  
  285. //
  286. // GAME FUNCTIONS
  287. //
  288. FAR vissprite_t    vissprites[MAXVISSPRITES];
  289. vissprite_t*    vissprite_p;
  290. int        newvissprite;
  291.  
  292.  
  293.  
  294. //
  295. // R_InitSprites
  296. // Called at program start.
  297. //
  298. void R_InitSprites (char** namelist)
  299. {
  300.     int        i;
  301.     
  302.     for (i=0 ; i<SCREENWIDTH ; i++)
  303.     {
  304.     negonearray[i] = -1;
  305.     }
  306.     
  307.     R_InitSpriteDefs (namelist);
  308. }
  309.  
  310.  
  311.  
  312. //
  313. // R_ClearSprites
  314. // Called at frame start.
  315. //
  316. void R_ClearSprites (void)
  317. {
  318.     vissprite_p = vissprites;
  319. }
  320.  
  321.  
  322. //
  323. // R_NewVisSprite
  324. //
  325. vissprite_t    overflowsprite;
  326.  
  327. vissprite_t* R_NewVisSprite (void)
  328. {
  329.     if (vissprite_p == &vissprites[MAXVISSPRITES])
  330.     return &overflowsprite;
  331.     
  332.     vissprite_p++;
  333.     return vissprite_p-1;
  334. }
  335.  
  336.  
  337.  
  338. //
  339. // R_DrawMaskedColumn
  340. // Used for sprites and masked mid textures.
  341. // Masked means: partly transparent, i.e. stored
  342. //  in posts/runs of opaque pixels.
  343. //
  344. short*        mfloorclip;
  345. short*        mceilingclip;
  346.  
  347. fixed_t        spryscale;
  348. fixed_t        sprtopscreen;
  349.  
  350. //#ifndef AMIGA
  351. void R_DrawMaskedColumn (column_t* column)
  352. {
  353.     int        topscreen;
  354.     int     bottomscreen;
  355.     fixed_t    basetexturemid;
  356.     
  357.     basetexturemid = dc_texturemid;
  358.     
  359.     for ( ; column->topdelta != 0xff ; ) 
  360.     {
  361.     // calculate unclipped screen coordinates
  362.     //  for post
  363.     topscreen = sprtopscreen + spryscale*column->topdelta;
  364.     bottomscreen = topscreen + spryscale*column->length;
  365.  
  366.     dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
  367.     dc_yh = (bottomscreen-1)>>FRACBITS;
  368.         
  369.     if (dc_yh >= mfloorclip[dc_x])
  370.         dc_yh = mfloorclip[dc_x]-1;
  371.     if (dc_yl <= mceilingclip[dc_x])
  372.         dc_yl = mceilingclip[dc_x]+1;
  373.  
  374.     if (dc_yl <= dc_yh)
  375.     {
  376.         dc_source = (byte *)column + 3;
  377.         dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
  378.         // dc_source = (byte *)column + 3 - column->topdelta;
  379.  
  380.         // Drawn by either R_DrawColumn
  381.         //  or (SHADOW) R_DrawFuzzColumn.
  382.         colfunc ();    
  383.     }
  384.     column = (column_t *)(  (byte *)column + column->length + 4);
  385.     }
  386.     
  387.     dc_texturemid = basetexturemid;
  388. }
  389. //#endif
  390.  
  391.  
  392.  
  393. //
  394. // R_DrawVisSprite
  395. //  mfloorclip and mceilingclip should also be set.
  396. //
  397. void
  398. R_DrawVisSprite
  399. ( vissprite_t*        vis,
  400.   int            x1,
  401.   int            x2 )
  402. {
  403.     column_t*        column;
  404.     int            texturecolumn;
  405.     fixed_t        frac;
  406.     patch_t*        patch;
  407.     
  408. //#ifdef AMIGA
  409. //    int            type = TYPE_NORMAL;
  410. //#endif
  411.  
  412.     
  413.     patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
  414.  
  415.     dc_colormap = vis->colormap;
  416.     
  417.     if (!dc_colormap)
  418.     {
  419. //#ifndef AMIGA
  420.     // NULL colormap = shadow draw
  421.     colfunc = fuzzcolfunc;
  422. //#else
  423. //        type = TYPE_FUZZ;
  424. //#endif
  425.     }
  426.     else if (vis->mobjflags & MF_TRANSLATION)
  427.     {
  428. //#ifndef AMIGA
  429.     colfunc = transcolfunc;
  430. //#else
  431. //        type = TYPE_TRANSL;
  432. //#endif
  433.     dc_translation = translationtables - 256 +
  434.         ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );
  435.     }
  436.     
  437.     dc_iscale = iabs(vis->xiscale)>>detailshift;
  438.     dc_texturemid = vis->texturemid;
  439.     frac = vis->startfrac;
  440.     spryscale = vis->scale;
  441.     sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
  442.     
  443.     for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)
  444.     {
  445.     texturecolumn = frac>>FRACBITS;
  446. #ifdef RANGECHECK
  447.     if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
  448.         I_Error ("R_DrawSpriteRange: bad texturecolumn");
  449. #endif
  450.     column = (column_t *) ((byte *)patch +
  451.                    LONG(patch->columnofs[texturecolumn]));
  452.  
  453. //#ifndef AMIGA
  454.      R_DrawMaskedColumn (column);
  455. //#else
  456. //    R_DrawMaskedColumnAmi (column, type);
  457. //#endif
  458.     }
  459.  
  460.     colfunc = basecolfunc;
  461. }
  462.  
  463.  
  464.  
  465. //
  466. // R_ProjectSprite
  467. // Generates a vissprite for a thing
  468. //  if it might be visible.
  469. //
  470. void R_ProjectSprite (mobj_t* thing)
  471. {
  472.     fixed_t        tr_x;
  473.     fixed_t        tr_y;
  474.     
  475.     fixed_t        gxt;
  476.     fixed_t        gyt;
  477.     
  478.     fixed_t        tx;
  479.     fixed_t        tz;
  480.  
  481.     fixed_t        xscale;
  482.     
  483.     int            x1;
  484.     int            x2;
  485.  
  486.     spritedef_t*    sprdef;
  487.     spriteframe_t*    sprframe;
  488.     int            lump;
  489.     
  490.     unsigned        rot;
  491.     boolean        flip;
  492.     
  493.     int            index;
  494.  
  495.     vissprite_t*    vis;
  496.     
  497.     angle_t        ang;
  498.     fixed_t        iscale;
  499.     
  500.     // transform the origin point
  501.     tr_x = thing->x - viewx;
  502.     tr_y = thing->y - viewy;
  503.     
  504.     gxt = FixedMul(tr_x,viewcos); 
  505.     gyt = -FixedMul(tr_y,viewsin);
  506.     
  507.     tz = gxt-gyt; 
  508.  
  509.     // thing is behind view plane?
  510.     if (tz < MINZ)
  511.     return;
  512.     
  513.     xscale = FixedDiv(projection, tz);
  514.     
  515.     gxt = -FixedMul(tr_x,viewsin); 
  516.     gyt = FixedMul(tr_y,viewcos); 
  517.     tx = -(gyt+gxt); 
  518.  
  519.     // too far off the side?
  520.     if (iabs(tx)>(tz<<2))
  521.     return;
  522.     
  523.     // decide which patch to use for sprite relative to player
  524. #ifdef RANGECHECK
  525.     if ((unsigned)thing->sprite >= numsprites)
  526.     I_Error ("R_ProjectSprite: invalid sprite number %i ",
  527.          thing->sprite);
  528. #endif
  529.     sprdef = &sprites[thing->sprite];
  530. #ifdef RANGECHECK
  531.     if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
  532.     I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  533.          thing->sprite, thing->frame);
  534. #endif
  535.     sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
  536.  
  537.     if (sprframe->rotate)
  538.     {
  539.     // choose a different rotation based on player view
  540.     ang = R_PointToAngle (thing->x, thing->y);
  541.     rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
  542.     lump = sprframe->lump[rot];
  543.     flip = (boolean)sprframe->flip[rot];
  544.     }
  545.     else
  546.     {
  547.     // use single rotation for all views
  548.     lump = sprframe->lump[0];
  549.     flip = (boolean)sprframe->flip[0];
  550.     }
  551.     
  552.     // calculate edges of the shape
  553.     tx -= spriteoffset[lump];    
  554.     x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
  555.  
  556.     // off the right side?
  557.     if (x1 > viewwidth)
  558.     return;
  559.     
  560.     tx +=  spritewidth[lump];
  561.     x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
  562.  
  563.     // off the left side
  564.     if (x2 < 0)
  565.     return;
  566.     
  567.     // store information in a vissprite
  568.     vis = R_NewVisSprite ();
  569.     vis->mobjflags = thing->flags;
  570.     vis->scale = xscale<<detailshift;
  571.     vis->gx = thing->x;
  572.     vis->gy = thing->y;
  573.     vis->gz = thing->z;
  574.     vis->gzt = thing->z + spritetopoffset[lump];
  575.     vis->texturemid = vis->gzt - viewz;
  576.     vis->x1 = x1 < 0 ? 0 : x1;
  577.     vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;    
  578.     iscale = FixedDiv (FRACUNIT, xscale);
  579.  
  580.     if (flip)
  581.     {
  582.     vis->startfrac = spritewidth[lump]-1;
  583.     vis->xiscale = -iscale;
  584.     }
  585.     else
  586.     {
  587.     vis->startfrac = 0;
  588.     vis->xiscale = iscale;
  589.     }
  590.  
  591.     if (vis->x1 > x1)
  592.     vis->startfrac += vis->xiscale*(vis->x1-x1);
  593.     vis->patch = lump;
  594.     
  595.     // get light level
  596.     if (thing->flags & MF_SHADOW)
  597.     {
  598.     // shadow draw
  599.     vis->colormap = NULL;
  600.     }
  601.     else if (fixedcolormap)
  602.     {
  603.     // fixed map
  604.     vis->colormap = fixedcolormap;
  605.     }
  606.     else if (thing->frame & FF_FULLBRIGHT)
  607.     {
  608.     // full bright
  609.     vis->colormap = colormaps;
  610.     }
  611.     
  612.     else
  613.     {
  614.     // diminished light
  615.     index = xscale>>(LIGHTSCALESHIFT-detailshift);
  616.  
  617.     if (index >= MAXLIGHTSCALE) 
  618.         index = MAXLIGHTSCALE-1;
  619.  
  620.     vis->colormap = spritelights[index];
  621.     }    
  622. }
  623.  
  624.  
  625.  
  626.  
  627. //
  628. // R_AddSprites
  629. // During BSP traversal, this adds sprites by sector.
  630. //
  631. void R_AddSprites (sector_t* sec)
  632. {
  633.     mobj_t*        thing;
  634.     int            lightnum;
  635.  
  636.     // BSP is traversed by subsector.
  637.     // A sector might have been split into several
  638.     //  subsectors during BSP building.
  639.     // Thus we check whether its already added.
  640.     if (sec->validcount == validcount)
  641.     return;        
  642.  
  643.     // Well, now it will be done.
  644.     sec->validcount = validcount;
  645.     
  646.     lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight;
  647.  
  648.     if (lightnum < 0)        
  649.     spritelights = scalelight[0];
  650.     else if (lightnum >= LIGHTLEVELS)
  651.     spritelights = scalelight[LIGHTLEVELS-1];
  652.     else
  653.     spritelights = scalelight[lightnum];
  654.  
  655.     // Handle all things in sector.
  656.     for (thing = sec->thinglist ; thing ; thing = thing->snext)
  657.     R_ProjectSprite (thing);
  658. }
  659.  
  660.  
  661. //
  662. // R_DrawPSprite
  663. //
  664. void R_DrawPSprite (pspdef_t* psp)
  665. {
  666.     fixed_t        tx;
  667.     int            x1;
  668.     int            x2;
  669.     spritedef_t*    sprdef;
  670.     spriteframe_t*    sprframe;
  671.     int            lump;
  672.     boolean        flip;
  673.     vissprite_t*    vis;
  674.     vissprite_t        avis;
  675.     
  676.     // decide which patch to use
  677. #ifdef RANGECHECK
  678.     if ( (unsigned)psp->state->sprite >= numsprites)
  679.     I_Error ("R_ProjectSprite: invalid sprite number %i ",
  680.          psp->state->sprite);
  681. #endif
  682.     sprdef = &sprites[psp->state->sprite];
  683. #ifdef RANGECHECK
  684.     if ( (psp->state->frame & FF_FRAMEMASK)  >= sprdef->numframes)
  685.     I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  686.          psp->state->sprite, psp->state->frame);
  687. #endif
  688.     sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
  689.  
  690.     lump = sprframe->lump[0];
  691.     flip = (boolean)sprframe->flip[0];
  692.     
  693.     // calculate edges of the shape
  694.     tx = psp->sx-160*FRACUNIT;
  695.     
  696.     tx -= spriteoffset[lump];    
  697.     x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
  698.  
  699.     // off the right side
  700.     if (x1 > viewwidth)
  701.     return;        
  702.  
  703.     tx +=  spritewidth[lump];
  704.     x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
  705.  
  706.     // off the left side
  707.     if (x2 < 0)
  708.     return;
  709.     
  710.     // store information in a vissprite
  711.     vis = &avis;
  712.     vis->mobjflags = 0;
  713.     vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]);
  714.     vis->x1 = x1 < 0 ? 0 : x1;
  715.     vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;    
  716.     vis->scale = pspritescale<<detailshift;
  717.     
  718.     if (flip)
  719.     {
  720.     vis->xiscale = -pspriteiscale;
  721.     vis->startfrac = spritewidth[lump]-1;
  722.     }
  723.     else
  724.     {
  725.     vis->xiscale = pspriteiscale;
  726.     vis->startfrac = 0;
  727.     }
  728.     
  729.     if (vis->x1 > x1)
  730.     vis->startfrac += vis->xiscale*(vis->x1-x1);
  731.  
  732.     vis->patch = lump;
  733.  
  734.     if (viewplayer->powers[pw_invisibility] > 4*32
  735.     || viewplayer->powers[pw_invisibility] & 8)
  736.     {
  737.     // shadow draw
  738.     vis->colormap = NULL;
  739.     }
  740.     else if (fixedcolormap)
  741.     {
  742.     // fixed color
  743.     vis->colormap = fixedcolormap;
  744.     }
  745.     else if (psp->state->frame & FF_FULLBRIGHT)
  746.     {
  747.     // full bright
  748.     vis->colormap = colormaps;
  749.     }
  750.     else
  751.     {
  752.     // local light
  753.     vis->colormap = spritelights[MAXLIGHTSCALE-1];
  754.     }
  755.     
  756.     R_DrawVisSprite (vis, vis->x1, vis->x2);
  757. }
  758.  
  759.  
  760.  
  761. //
  762. // R_DrawPlayerSprites
  763. //
  764. void R_DrawPlayerSprites (void)
  765. {
  766.     int        i;
  767.     int        lightnum;
  768.     pspdef_t*    psp;
  769.     
  770.     // get light level
  771.     lightnum =
  772.     (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) 
  773.     +extralight;
  774.  
  775.     if (lightnum < 0)        
  776.     spritelights = scalelight[0];
  777.     else if (lightnum >= LIGHTLEVELS)
  778.     spritelights = scalelight[LIGHTLEVELS-1];
  779.     else
  780.     spritelights = scalelight[lightnum];
  781.     
  782.     // clip to screen bounds
  783.     mfloorclip = screenheightarray;
  784.     mceilingclip = negonearray;
  785.     
  786.     // add all active psprites
  787.     for (i=0, psp=viewplayer->psprites;
  788.      i<NUMPSPRITES;
  789.      i++,psp++)
  790.     {
  791.     if (psp->state)
  792.         R_DrawPSprite (psp);
  793.     }
  794. }
  795.  
  796.  
  797.  
  798.  
  799. //
  800. // R_SortVisSprites
  801. //
  802. vissprite_t    vsprsortedhead;
  803.  
  804.  
  805. void R_SortVisSprites (void)
  806. {
  807.     int            i;
  808.     int            count;
  809.     vissprite_t*    ds;
  810.     vissprite_t*    best;
  811.     vissprite_t        unsorted;
  812.     fixed_t        bestscale;
  813.  
  814.     count = vissprite_p - vissprites;
  815.     
  816.     unsorted.next = unsorted.prev = &unsorted;
  817.  
  818.     if (!count)
  819.     return;
  820.         
  821.     for (ds=vissprites ; ds<vissprite_p ; ds++)
  822.     {
  823.     ds->next = ds+1;
  824.     ds->prev = ds-1;
  825.     }
  826.     
  827.     vissprites[0].prev = &unsorted;
  828.     unsorted.next = &vissprites[0];
  829.     (vissprite_p-1)->next = &unsorted;
  830.     unsorted.prev = vissprite_p-1;
  831.     
  832.     // pull the vissprites out by scale
  833.     //best = 0;        // shut up the compiler warning
  834.     vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
  835.     for (i=0 ; i<count ; i++)
  836.     {
  837.     bestscale = MAXINT;
  838.     for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)
  839.     {
  840.         if (ds->scale < bestscale)
  841.         {
  842.         bestscale = ds->scale;
  843.         best = ds;
  844.         }
  845.     }
  846.     best->next->prev = best->prev;
  847.     best->prev->next = best->next;
  848.     best->next = &vsprsortedhead;
  849.     best->prev = vsprsortedhead.prev;
  850.     vsprsortedhead.prev->next = best;
  851.     vsprsortedhead.prev = best;
  852.     }
  853. }
  854.  
  855.  
  856.  
  857. //
  858. // R_DrawSprite
  859. //
  860. void R_DrawSprite (vissprite_t* spr)
  861. {
  862.     drawseg_t*        ds;
  863.     short        clipbot[SCREENWIDTH];
  864.     short        cliptop[SCREENWIDTH];
  865.     int            x;
  866.     int            r1;
  867.     int            r2;
  868.     fixed_t        scale;
  869.     fixed_t        lowscale;
  870.     int            silhouette;
  871.         
  872.     for (x = spr->x1 ; x<=spr->x2 ; x++)
  873.     clipbot[x] = cliptop[x] = -2;
  874.     
  875.     // Scan drawsegs from end to start for obscuring segs.
  876.     // The first drawseg that has a greater scale
  877.     //  is the clip seg.
  878.     for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  879.     {
  880.     // determine if the drawseg obscures the sprite
  881.     if (ds->x1 > spr->x2
  882.         || ds->x2 < spr->x1
  883.         || (!ds->silhouette
  884.         && !ds->maskedtexturecol) )
  885.     {
  886.         // does not cover sprite
  887.         continue;
  888.     }
  889.             
  890.     r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
  891.     r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
  892.  
  893.     if (ds->scale1 > ds->scale2)
  894.     {
  895.         lowscale = ds->scale2;
  896.         scale = ds->scale1;
  897.     }
  898.     else
  899.     {
  900.         lowscale = ds->scale1;
  901.         scale = ds->scale2;
  902.     }
  903.         
  904.     if (scale < spr->scale
  905.         || ( lowscale < spr->scale
  906.          && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
  907.     {
  908.         // masked mid texture?
  909.         if (ds->maskedtexturecol)    
  910.         R_RenderMaskedSegRange (ds, r1, r2);
  911.         // seg is behind sprite
  912.         continue;            
  913.     }
  914.  
  915.     
  916.     // clip this piece of the sprite
  917.     silhouette = ds->silhouette;
  918.     
  919.     if (spr->gz >= ds->bsilheight)
  920.         silhouette &= ~SIL_BOTTOM;
  921.  
  922.     if (spr->gzt <= ds->tsilheight)
  923.         silhouette &= ~SIL_TOP;
  924.             
  925.     if (silhouette == 1)
  926.     {
  927.         // bottom sil
  928.         for (x=r1 ; x<=r2 ; x++)
  929.         if (clipbot[x] == -2)
  930.             clipbot[x] = ds->sprbottomclip[x];
  931.     }
  932.     else if (silhouette == 2)
  933.     {
  934.         // top sil
  935.         for (x=r1 ; x<=r2 ; x++)
  936.         if (cliptop[x] == -2)
  937.             cliptop[x] = ds->sprtopclip[x];
  938.     }
  939.     else if (silhouette == 3)
  940.     {
  941.         // both
  942.         for (x=r1 ; x<=r2 ; x++)
  943.         {
  944.         if (clipbot[x] == -2)
  945.             clipbot[x] = ds->sprbottomclip[x];
  946.         if (cliptop[x] == -2)
  947.             cliptop[x] = ds->sprtopclip[x];
  948.         }
  949.     }
  950.         
  951.     }
  952.     
  953.     // all clipping has been performed, so draw the sprite
  954.  
  955.     // check for unclipped columns
  956.     for (x = spr->x1 ; x<=spr->x2 ; x++)
  957.     {
  958.     if (clipbot[x] == -2)        
  959.         clipbot[x] = viewheight;
  960.  
  961.     if (cliptop[x] == -2)
  962.         cliptop[x] = -1;
  963.     }
  964.         
  965.     mfloorclip = clipbot;
  966.     mceilingclip = cliptop;
  967.     R_DrawVisSprite (spr, spr->x1, spr->x2);
  968. }
  969.  
  970.  
  971.  
  972.  
  973. //
  974. // R_DrawMasked
  975. //
  976. void R_DrawMasked (void)
  977. {
  978.     vissprite_t*    spr;
  979.     drawseg_t*        ds;
  980.     
  981.     R_SortVisSprites ();
  982.  
  983.     if (vissprite_p > vissprites)
  984.     {
  985.     // draw all vissprites back to front
  986.     for (spr = vsprsortedhead.next ;
  987.          spr != &vsprsortedhead ;
  988.          spr=spr->next)
  989.     {
  990.         
  991.         R_DrawSprite (spr);
  992.     }
  993.     }
  994.     
  995.     // render any remaining masked mid textures
  996.     for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  997.     if (ds->maskedtexturecol)
  998.         R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
  999.     
  1000.     // draw the psprites on top of everything
  1001.     //  but does not draw on side views
  1002.     if (!viewangleoffset)        
  1003.     R_DrawPlayerSprites ();
  1004. }
  1005.  
  1006.  
  1007.  
  1008.